package cn.hfjava.kz.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hfjava.kz.config.properties.KzUploadProperties;
import cn.hfjava.kz.entity.po.Student;
import cn.hfjava.kz.entity.po.User;
import cn.hfjava.kz.exception.BizException;
import cn.hfjava.kz.service.StudentService;
import cn.hfjava.kz.service.UserService;
import cn.hutool.core.io.file.FileNameUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 公共上传前端控制器
 * @author lds
 * @date 2024/07/15 10:23
 */
@RestController
@RequestMapping("/api/v1/upload")
@Tag(name = "文件上传接口")
@Slf4j
public class UploadController {

    @Resource
    private KzUploadProperties kzUploadProperties;

    @Resource
    private StudentService studentService;

    @Resource
    private MultipartConfigElement multipartConfigElement;

    private static final List<String> IMAGE_TYPE = Arrays.asList("png","jpg","jpeg");
    private static final List<String> FILE_TYPE = Arrays.asList("pdf");

    @Operation(summary = "上传图片")
    @PostMapping(value = "/image",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public SaResult uploadImage(
            @RequestPart(name="file",required = true) MultipartFile file,
            @RequestParam(value = "studentId") Integer studentId,
            @RequestParam(value = "imageType",required = false) String imageType){
        // png、jpg、jpeg   10MB
        if(file == null || file.getSize() == 0){
            return SaResult.error("上传图片不能为空");
        }
        String fileName = file.getOriginalFilename();
        String fileSuffix = fileName.substring(fileName.lastIndexOf(".")); // .jpg
        String fileExt = FileNameUtil.extName(fileName); // jpg
        Long fileSize = file.getSize();
        if(! IMAGE_TYPE.contains(fileExt)){
            return SaResult.error("上传图片格式错误，仅支持(.jpg,.jpeg,.png)格式");
        }
        if(fileSize > multipartConfigElement.getMaxFileSize()){
            return SaResult.error("上传图片大小不能超过10MB");
        }

        Student student = studentService.getById(studentId);
        if(student == null) {
            return SaResult.error("此考生不存在");
        }

        /*
         *  手机号_身份证正面.jpg
         *  手机号_身份证反面.jpg
         *  手机号_毕业证书.jpg
         *  手机号_个人相片.jpg
         *  手机号_职工个人参保证明.pdf
         */
        switch (imageType) {
            case "idCardFront":
                 fileName = student.getPhone() + "_身份证(人像面)" + fileSuffix;
                break;
            case "idCardBack":
                fileName = student.getPhone() + "_身份证(国徽面)" + fileSuffix;
                break;
            case "CertNo":
                fileName = student.getPhone() + "_毕业证书" + fileSuffix;
                break;
            case "Photo":
                fileName = student.getPhone() + "_个人相片" + fileSuffix;
                break;
            default:
                return SaResult.error("图片类型错误");
        }


        String uploadPath = kzUploadProperties.getUploadPath();
      /*  LocalDateTime now = LocalDateTime.now();
        String yearPath = String.valueOf(now.getYear());
        String monthPath = String.valueOf(now.getMonthValue());
        String dayPath = String.valueOf(now.getDayOfMonth());*/
        //String dirPath = yearPath + "/" + monthPath + "/" + dayPath + "/" + userEntity.getUsername() + "/";

        String dirPath = student.getName().concat("_").concat(student.getPhone()) + "/";  // D:/kz/uploadPath/20240816/张三/

        File dirFile = new File(uploadPath,dirPath);
        if (! dirFile.exists()) {
            dirFile.mkdirs();
        }
        File destFile = new File(dirFile,fileName);
        try {
            file.transferTo(destFile);
            String imagePath = kzUploadProperties.getAssetsUrl()
                    .replaceFirst("\\*\\*","")  + dirPath +  fileName;
            String imageUrl = kzUploadProperties.getBaseUrl() +imagePath;
            Map<String,String> imageMap = new HashMap<>();
            imageMap.put("url",imageUrl);
            imageMap.put("path",imagePath);

            return SaResult.ok("上传图片成功").data(imageMap);
        } catch (IOException ex) {
            throw new BizException(500,"上传图片失败",ex);
        }
    }


    @Operation(summary = "上传文件")
    @PostMapping(value = "/file",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public SaResult uploadPdfFile(
            @RequestPart(name="file",required = true) MultipartFile file,
            @RequestParam(name="studentId",required = true) Integer studentId){
        // pdf、doc、docx  10MB
        if(file == null || file.getSize() == 0){
            return SaResult.error("上传文件不能为空");
        }
        String fileName = file.getOriginalFilename();
        //String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1); // jpg
        String fileExt = FileNameUtil.extName(fileName); // jpg，不是.jpg
        Long fileSize = file.getSize();
        if(! FILE_TYPE.contains(fileExt)){
            return SaResult.error("上传文件格式错误，仅支持(.pdf)格式");
        }
        if(fileSize > multipartConfigElement.getMaxFileSize()){
            return SaResult.error("上传文件大小不能超过10MB");
        }

        //Integer loginId = StpUtil.getLoginIdAsInt();
        //User userEntity = userService.getById(loginId);


        Student student = studentService.getById(studentId);
        if(student == null) {
            return SaResult.error("此考生不存在");
        }

        fileName = student.getPhone() + "_职工个人参保证明.pdf";

        String uploadPath = kzUploadProperties.getUploadPath();
        /*LocalDateTime now = LocalDateTime.now();
        String yearPath = String.valueOf(now.getYear());
        String monthPath = String.valueOf(now.getMonthValue());
        String dayPath = String.valueOf(now.getDayOfMonth());
        String dirPath = yearPath + "/" + monthPath + "/" + dayPath + "/" + userEntity.getUsername() + "/";*/

        String dirPath = student.getName().concat("_").concat(student.getPhone()) + "/"; //   D:/kz/uploadPath/20240816/张三/

        File dirFile = new File(uploadPath,dirPath);
        if (! dirFile.exists()) {
            dirFile.mkdirs();
        }

        File destFile = new File(dirFile,fileName);

        try {
            file.transferTo(destFile);
            String filePath = kzUploadProperties.getAssetsUrl()
                    .replaceFirst("\\*\\*","")  + dirPath +  fileName;
            String fileUrl = kzUploadProperties.getBaseUrl() + filePath;
            Map<String,String> imageMap = new HashMap<>();
            imageMap.put("url",fileUrl);
            imageMap.put("path",filePath);
            return SaResult.ok("上传文件成功").data(imageMap);
        } catch (IOException ex) {
            throw new BizException(500,"上传文件失败",ex);
        }
    }



    @PostMapping("/api/download")
    @Operation(summary = "下载文件")
    public void download(@RequestParam(value = "filename",required = true) String filename,
                         HttpServletResponse response) throws IOException {
        // 2024/07/16/李政浩/xxx.jpg
        // 2024/07/16/李政浩/xxx.docx
        if(! StringUtils.hasLength(filename)) {
            throw new RuntimeException("下载文件为空");
        }
        File file = new File(kzUploadProperties.getUploadPath(),filename);
        if(! file.exists()) {
            throw new RuntimeException("下载文件不存在");
        }
        // 设置响应报文
        response.setContentType("application/octet-stream");
        // 指定下载文件名(attachment-以下载方式保存到本地，inline-在线预览)
        response.addHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        try(
                InputStream is = new FileInputStream(file);
                OutputStream os = response.getOutputStream()
        ){
            byte[] buffer = new byte[1024];
            int readBytes = 0;

            while((readBytes = is.read(buffer)) != -1) {
                os.write(buffer, 0, readBytes);
                os.flush();
            }
        }catch (IOException ex) {
            ex.printStackTrace();
            throw new RuntimeException("文件下载失败");
        }
    }

}
